﻿using Magicodes.ExporterAndImporter.Excel;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using MT.Enterprise.Utils.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.Common;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Engine;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.FrameOrder.Dto;
using NP.BPMReportPlatform.HR;
using NP.BPMReportPlatform.Utils;
using NP.Enterprise.Utils.Http;
using NPOI.SS.Formula.Functions;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Entities;
using static NP.BPMReportPlatform.SF.Dto.SFDto;

namespace NP.BPMReportPlatform.FrameOrder
{
    public class FrameOrderService : BPMReportPlatformAppService, IFrameOrderService
    {
        private readonly SqlSugarClient _db;
        private readonly SqlSugarClient _dbPlatform;
        private readonly SqlSugarClient _dbEngine;
        private readonly IBPMUtilsAppService _bPMUtilsApp;
        private readonly IBPMPlatformAppService _iBPMPlatformApp;
        private readonly INPRestHttpHelper _nPRestHttp;
        private readonly IHRAppService _hrAppService;
        private readonly string _frameOrderBatchConfirUrl;
        private readonly string _tokenUrl;
        private readonly string _esbNewErpApi;
        private readonly ICommonService _commonService;
        private readonly IExcelImporter _importer;
        private readonly string _esbSFPushUrl;
        private readonly string _reportUrl;


        public FrameOrderService(ISqlSugarAppService sqlSugarAppService, IBPMUtilsAppService bPMUtilsApp
            , IBPMPlatformAppService iBPMPlatformApp, INPRestHttpHelper nPRestHttp,
            IConfiguration configuration, IHRAppService hrAppService,
            ICommonService commonService, IExcelImporter importer)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _bPMUtilsApp = bPMUtilsApp;
            _iBPMPlatformApp = iBPMPlatformApp;
            _nPRestHttp = nPRestHttp;
            _hrAppService = hrAppService;
            _frameOrderBatchConfirUrl = configuration["BPM:FrameOrderBatchConfirUrl"];
            _tokenUrl = configuration["Nippon:FrameOrder:TokenUrl"];
            _esbNewErpApi = configuration["Nippon:FrameOrder:ESBNEWERPAPI"];
            _esbSFPushUrl = configuration["Nippon:ESB:SYQ_ESB_SAPSF_API"];
            _reportUrl = configuration["Nippon:BPMReportWeb"];
            _commonService = commonService;
            _importer = importer;

        }

        public async Task<PagedResultDto<GetFrameOrderOutput>> GetAllAsync(GetFrameOrderInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = await GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            listViewDto = await AssignList(listViewDto);

            if (listViewDto.Count() > 0 && input.ProcessTopic == "驻外补贴")
            {
                var instancenumbers = listViewDto.Select(t => t.InstanceNumber).ToList();
                var totalRSZWBTChilds = _db.Queryable<FrameOrderChildrszwbt>().Where(t => instancenumbers.Contains(t.InstanceNumber)).ToList();
                listViewDto.ForEach(t =>
                {
                    var child = totalRSZWBTChilds.FirstOrDefault(c => c.InstanceNumber == t.InstanceNumber);
                    t.TransportationSubsidy2 = child?.Rent.ToOurDecimal() > child?.RentalAllowance.ToOurDecimal() ? child?.RentalAllowance : child?.Rent; // 充当租房补贴
                    t.HRBPTransportationSubsidy = child?.FamilyVisitsNumber;// 充当探亲假次数
                    t.HRBPTransportationSubsidy2 = child?.SettleFee;// 充当一次性按家费
                });
            }

            //返回结果
            return new PagedResultDto<GetFrameOrderOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        /// <summary>
        /// 探亲次数报表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<FrameOrderChildrszwbt>> GetVisitAsync(GetFrameOrderInput input)
        {
            RefAsync<int> totalCount = 0;

            var workNumbers = _commonService.GetUserByRoleFilter(CurrentUser.UserName, Contract.Dtos.RelationshipTypeEnum.HRBP);
            bool isAdmin = workNumbers.Contains("9999999999");

            var splitChat = new char[] { ',', ';', '，', '；' };
            var instanceResult = await _db.Queryable<FrameOrderChildrszwbt>()
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), t => t.InstanceNumber.Contains(input.InstanceNumber))
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName),
                    t => t.ApplyName.Contains(input.AddUserName) || t.ApplyNumber.Contains(input.AddUserName))
                .WhereIF(!input.IsAdmin && !isAdmin, t => SqlFunc.ContainsArray(workNumbers, t.ApplyNumber))
                .Select(t => t).ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            //返回结果
            return new PagedResultDto<FrameOrderChildrszwbt>()
            {
                TotalCount = totalCount,
                Items = instanceResult
            };
        }

        /// <summary>
        /// 探亲次数重新推送
        /// </summary>
        /// <param name="instanceNumber">流程编号</param>
        /// <returns></returns>
        public async Task<string> PushVisitRetryAsync(string instanceNumber)
        {
            var entity = await _db.Queryable<FrameOrderChildrszwbt>().Where(b => b.InstanceNumber == instanceNumber).FirstAsync();
            if (entity == null)
            {
                return "未找到此流程数据!";
            }

            ResultInfo result = SendData(entity);

            if (result != null)
            {
                SendPermissionsData(entity);

                entity.PushResult1 = result.resCode + ":" + result.resMsg;
                _db.Updateable(entity).UpdateColumns(t => t.PushResult1).ExecuteCommand();
                return result.resMsg;
            }
            return string.Empty;
        }

        /// <summary>
        /// 驻外补贴重新推送给SF
        /// </summary>
        /// <param name="instanceNumber"></param>
        /// <returns></returns>
        public async Task<string> PushRSZWToSF(string instanceNumber)
        {
            var entity = await _db.Queryable<FrameOrderChildrszwbt>().Where(b => b.InstanceNumber == instanceNumber).FirstAsync();
            if (entity == null)
            {
                return "未找到此流程数据!";
            }

            SendToSF(entity);
            return string.Empty;
        }

        private ResultInfo SendData(FrameOrderChildrszwbt entity)
        {
            var headers = new Dictionary<string, string>
            {
                { "requestId", Guid.NewGuid().ToString() },
                { "trackId", Guid.NewGuid().ToString() },
                { "sourceSystem", "BPMNEW" }
            };
            headers.Add("serviceName", "S_XXX_CloudPense_GetToken_S");

            string tokenUrl = _tokenUrl;
            var tokenResult = _nPRestHttp.PostAsync<TokenOutput>(tokenUrl, new TokenInput(), headers).Result;

            var token = tokenResult.resCode == 200000 ? tokenResult.data.access_token : string.Empty;

            headers.Remove("serviceName");
            headers.Add("serviceName", "S_XXX_CloudPense_ValueSynchronization_S");
            headers.Add("accessToken", token);

            var data = new List<object>();

            if (!string.IsNullOrEmpty(entity.FamilyVisitsNumber) && entity.FamilyVisitsNumber != "0")
            {
                data.Add(new
                {
                    code = "Expat",
                    value = "探亲次数" + entity.AssignDatebegin.Value.ToString("yyyyMMdd") + "-" + entity.AssignDateend.Value.ToString("yyyyMMdd"),
                    description = "",
                    type = entity.InstanceNumber + "_" + entity.ApplyNumber + "_1",
                    column1 = ConvertDateTimeToInt(entity.AssignDatebegin.Value).ToString(),
                    column2 = ConvertDateTimeToInt(entity.AssignDateend.Value).ToString(),
                    column3 = entity.FamilyVisitsNumber
                });
            }

            if (!string.IsNullOrEmpty(entity.SettleFee) && entity.SettleFee != "0")
            {
                data.Add(new
                {
                    code = "Settlefee",
                    value = "一次性安家费" + entity.AssignDatebegin.Value.ToString("yyyyMMdd") + "-" + entity.AssignDateend.Value.ToString("yyyyMMdd"),
                    description = "",
                    type = entity.InstanceNumber + "_" + entity.ApplyNumber + "_2",
                    column1 = ConvertDateTimeToInt(entity.AssignDatebegin.Value).ToString(),
                    column2 = ConvertDateTimeToInt(entity.AssignDateend.Value).ToString(),
                    column3 = entity.SettleFee
                });
            }

            var requestdto = new
            {
                bizId = Guid.NewGuid().ToString(),
                timestamp = ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000).ToString(),
                data = data
            };

            // 等待回调
            var content = System.Threading.Tasks.Task.Run(async () =>
                await _nPRestHttp.PostAsync<ResultInfo>(_esbNewErpApi, requestdto, headers)).Result;
            return content;
        }

        private ResultInfo SendPermissionsData(FrameOrderChildrszwbt entity)
        {
            var headers = new Dictionary<string, string>
            {
                { "requestId", Guid.NewGuid().ToString() },
                { "trackId", Guid.NewGuid().ToString() },
                { "sourceSystem", "BPMNEW" }
            };
            headers.Add("serviceName", "S_XXX_CloudPense_GetToken_S");

            string tokenUrl = _tokenUrl;
            var tokenResult = _nPRestHttp.PostAsync<TokenOutput>(tokenUrl, new TokenInput(), headers).Result;

            var token = tokenResult.resCode == 200000 ? tokenResult.data.access_token : string.Empty;

            headers.Remove("serviceName");
            headers.Add("serviceName", "S_XXX_CloudPense_PermissionSynchronization_S");
            headers.Add("accessToken", token);

            var data = new List<object>();

            if (!string.IsNullOrEmpty(entity.FamilyVisitsNumber) && entity.FamilyVisitsNumber != "0")
            {
                data.Add(new
                {
                    code = entity.InstanceNumber + "_" + entity.ApplyNumber + "_1",
                    lov_name = "Expat",
                    staff_code = new string[] { entity.ApplyNumber },

                });
            }

            if (!string.IsNullOrEmpty(entity.SettleFee) && entity.SettleFee != "0")
            {
                data.Add(new
                {
                    code = entity.InstanceNumber + "_" + entity.ApplyNumber + "_2",
                    lov_name = "Settlefee",
                    staff_code = new string[] { entity.ApplyNumber },
                });
            }

            var requestdto = new
            {
                bizId = Guid.NewGuid().ToString(),
                timestamp = ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000).ToString(),
                data = data
            };

            // 等待回调
            var content = System.Threading.Tasks.Task.Run(async () =>
                await _nPRestHttp.PostAsync<ResultInfo>(_esbNewErpApi, requestdto, headers)).Result;
            return content;
        }

        private void SendToSF(FrameOrderChildrszwbt entity)
        {
            try
            {
                Dictionary<string, string> dic = new Dictionary<string, string>()
                {
                    { "serviceName", "S_XXX_SF_Sfexpatriate_S" },
                    { "sourceSystem", "BPMNEW" }
                };

                // 数据整理
                var requestBody = new
                {
                    url = new { format = "json" },
                    body = new
                    {
                        __metadata = new
                        {
                            uri = $"cust_expatriate",
                            type = "SFOData.cust_expatriate"
                        },
                        externalCode = entity.ApplyNumber,
                        effectiveStartDate = ToSFStr(entity.AssignDatebegin.Value, true), // 生效日期
                        cust_originalworkplace = entity.OldWorkPlace == null ? string.Empty : entity.OldWorkPlace.Replace("[", string.Empty).Replace("]", string.Empty).Replace("\"", string.Empty).Replace(" ", string.Empty).Replace("\r", string.Empty).Replace("\n", string.Empty), // 原工作地
                        cust_newworkplace = entity.AssignWorkPlace == null ? string.Empty : entity.AssignWorkPlace.Replace("[", string.Empty).Replace("]", string.Empty).Replace("\"", string.Empty).Replace(" ", string.Empty).Replace("\r", string.Empty).Replace("\n", string.Empty), // 派往新工作地
                        cust_reason = entity.ApplyAssignReasons, // 申请外派理由
                        cust_target = entity.AssignPurpose, // 外派目的及目标
                        cust_periods = entity.AssignTimes, // 外派期数
                        cust_startmonth = entity.AssignDatebegin.Value.ToString("yyyy-MM"), // 外派开始月
                        cust_endmonth = entity.AssignDateend.Value.ToString("yyyy-MM"), // 外派结束月 "2024-12",
                        cust_processnumber = entity.InstanceNumber, // 流程号
                        cust_bpmlink = _reportUrl + "/report/frame-order/zwbtFrameOrder" // 固定传单据查询报表链接
                    },
                };
                var requeststr1 = JsonConvert.SerializeObject(requestBody).Replace("format", "$format");

                var resDataStr = _nPRestHttp.ESBPostAsync(_esbSFPushUrl, requeststr1, dic).Result;
                var resData = JsonConvert.DeserializeObject<SFRSZWBTPushResponse.SFRSZWBTPush>(resDataStr);

                // 数据处理
                if (resData?.d != null && resData?.d.Count > 0)
                {
                    entity.PushResult2 = resData.d[0].status == "OK" ? "1:success" : "-1:" + resData.d[0].message;
                }
            }
            catch (Exception ex)
            {
                entity.PushResult2 = "-1:" + ex.Message;
            }
            finally
            {
                if (entity != null)
                {
                    _db.Updateable(entity).UpdateColumns(t => new { t.PushResult2 }).ExecuteCommand();
                }
            }
        }

        /// <summary>
        /// 日期转时间戳
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        private long ConvertDateTimeToInt(DateTime time)
        {
            System.DateTime Time = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long TimeStamp = (time.Ticks - Time.Ticks) / 10000;   // 除10000调整为13位
            return TimeStamp;
        }

        /// <summary>
        /// 租房补贴记录查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<GetFrameOrderPullingRecordOutput>> GetRentalAllowanceAsync(GetFraneOrderPushRecordInput input)
        {
            RefAsync<int> totalCount = 0;
            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);
            var workNumbers = _commonService.GetUserByRoleFilter(CurrentUser.UserName, Contract.Dtos.RelationshipTypeEnum.HRBP);
            bool isAdmin = workNumbers.Contains("9999999999");
            var rst = await _db.Queryable<FrameOrderUsfeeAllowance>()
             .Where(a => a.allowance_type.Equals("房租补贴") || a.allowance_type.Equals("车辆使用补贴"))
             .WhereIF(!string.IsNullOrWhiteSpace(input.EmployeeNumber), a => a.employeeId.Contains(input.EmployeeNumber))
             .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), (a) => a.InstanceNumber.Contains(input.InstanceNumber))
             .WhereIF(!string.IsNullOrWhiteSpace(input.BusinessType), (a) => a.BusinessType == input.BusinessType)
             .WhereIF(!string.IsNullOrWhiteSpace(input.StartDate), (a) => a.StartDate >= Convert.ToDateTime(input.StartDate))
             .WhereIF(!string.IsNullOrWhiteSpace(input.EndDate), (a) => a.EndDate <= Convert.ToDateTime(input.EndDate))
             .WhereIF(!string.IsNullOrWhiteSpace(input.DataType), (a) => a.allowance_type.Contains(input.DataType))
             .WhereIF(!string.IsNullOrWhiteSpace(input.Year), (a) => a.year == input.Year)
             .WhereIF(!string.IsNullOrWhiteSpace(input.Month), (a) => a.month == input.Month)
             .WhereIF(!isAdmin, t => SqlFunc.ContainsArray(workNumbers, t.employeeId))
             .OrderBy(" InstanceNumber desc, year desc ,month*1 desc").Select((a) =>
                  new GetFrameOrderPullingRecordOutput
                  {
                      Allowance_Type = a.allowance_type,
                      EmployeeNumber = a.employeeId,
                      EmployeeName = a.employeeName,
                      Allowance_Lines = a.allowance_lines,
                      Year = a.year,
                      Month = a.month,
                      StartDate = a.StartDate == null ? "" : Convert.ToDateTime(a.StartDate).ToString("yyyy-MM-dd"),
                      EndDate = a.EndDate == null ? "" : Convert.ToDateTime(a.EndDate).ToString("yyyy-MM-dd"),
                      InstanceNumber = a.InstanceNumber,
                      IsOldData = a.IsOldData == true ? "是" : "否",
                      LasterSyncDate = a.LasterSyncDate,
                      UpdateDate = a.UpdateDate == null ? "" : Convert.ToDateTime(a.UpdateDate).ToString("yyyy-MM-dd"),
                      Id = a.ID.ToString(),// 主键
                  }).ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            rst.ForEach(x =>
            {
                x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId);
            });

            //返回结果
            return new PagedResultDto<GetFrameOrderPullingRecordOutput>()
            {
                TotalCount = totalCount,
                Items = rst
            };
        }

        /// <summary>
        /// 框架订单导入
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public async Task<ImportResultExt<FrameOrderImportDto.ImportInput>> ImporterExcelAsync(byte[] bytes)
        {
            Stream stream = new MemoryStream(bytes);
            var rst = await _importer.Import<FrameOrderImportDto.ImportInput>(stream);
            var importData = rst.Data;
            if (!rst.HasError)
            {
                foreach (var item in importData)
                {
                    // 探亲假次数,一次性按家费
                    var child = await SaveData(item);
                    if (item.Gdjt.ToOurInt() > 0)
                    {
                        // 固定津贴
                        UsualAllowanceDate(child);
                    }

                    // 租房补贴
                    if (item.Zfjt.ToOurInt() > 0)
                    {
                        RentSubsidies_UsfeeAllowance(child);
                    }
                }
            }
            var resp = new ImportResultExt<FrameOrderImportDto.ImportInput>()
            {
                Data = importData,
                Exception = rst.Exception,
                RowErrors = rst.RowErrors,
                TemplateErrors = rst.TemplateErrors
            };
            return resp;
        }
        public async Task<List<GetFrameOrderOutput>> ExportAsync(GetFrameOrderInput input)
        {
            var listQueryable = await GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            if (listViewDto.Count() > 0 && input.ProcessTopic == "驻外补贴")
            {
                var instancenumbers = listViewDto.Select(t => t.InstanceNumber).ToList();
                var totalRSZWBTChilds = _db.Queryable<FrameOrderChildrszwbt>().Where(t => instancenumbers.Contains(t.InstanceNumber)).ToList();
                listViewDto.ForEach(t =>
                {
                    var child = totalRSZWBTChilds.FirstOrDefault(c => c.InstanceNumber == t.InstanceNumber);
                    t.TransportationSubsidy2 = child?.Rent.ToOurDecimal() > child?.RentalAllowance.ToOurDecimal() ? child?.RentalAllowance : child?.Rent; // 充当租房补贴
                    t.HRBPTransportationSubsidy = child?.FamilyVisitsNumber;// 充当探亲假次数
                    t.HRBPTransportationSubsidy2 = child?.SettleFee;// 充当一次性按家费
                });
            }

            return await AssignList(listViewDto);
        }

        private async Task<List<GetFrameOrderOutput>> AssignList(List<GetFrameOrderOutput> listViewDto)
        {
            var dic = _dbPlatform.Queryable<Dictionaries>()
                .Where(t => t.TypeCode == "FOsqbtly" || t.TypeCode == "FOsqlx").ToList();
            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);

            var instanceids = listViewDto.Select(t => t.InstanceNumber).ToList();
            var approvers = GetApprovers(instanceids);
            listViewDto.ForEach(x =>
                {
                    if (approvers.ContainsKey(x.InstanceNumber))
                    {
                        x.Approve1 = approvers[x.InstanceNumber]["approver1"];
                        x.Approve2 = approvers[x.InstanceNumber]["approver2"];
                        x.Approve3 = approvers[x.InstanceNumber]["approver3"];
                        x.Approve4 = approvers[x.InstanceNumber]["approver4"];
                        x.Approve5 = approvers[x.InstanceNumber]["approver5"];
                        x.Approve6 = approvers[x.InstanceNumber]["approver6"];
                        x.Approve7 = approvers[x.InstanceNumber]["approver7"];
                    }

                    x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId);
                    x.ApplyTypeSubsidy = GetDicName(x.ApplyTypeSubsidy, dic);
                    x.BusinessType = GetBusinessType(x.BusinessType);
                    x.DocApplyType = GetDicName(x.DocApplyType, dic);
                    x.HRBPFinalSubsidyEndDate = getSubDate(x, 0);
                    x.HRBPFinalSubsidystartDate = getSubDate(x, 1);
                    x.HRBPFinalTransportationSubsidy = getMoney(x, 0);
                    x.HRBPFinalTransportationSubsidy2 = getMoney(x, 1);

                    x.InstanceType = GetInstanceType(x.InstanceNumber);
                }
            );
            return listViewDto;
        }


        /// <summary>
        /// 获取审批人(外面只掉一次，别循环调用)
        /// </summary>
        /// <returns>key:流程号，value：{key:approver1,value:name}</returns>
        private Dictionary<string, Dictionary<string, string>> GetApprovers(List<string> instanceNumbers)
        {
            Dictionary<string, Dictionary<string, string>> result = new Dictionary<string, Dictionary<string, string>>();
            if (instanceNumbers == null || instanceNumbers.Count() == 0)
            {
                return null;
            }

            var activites = _dbEngine.Queryable<Activities>().Where(t => instanceNumbers.Contains(t.InstanceNumber)).OrderBy(t => t.ArriveTime).ToList();
            var tasks = _dbEngine.Queryable<Tasks>().Where(t => instanceNumbers.Contains(t.InstanceNumber)).OrderBy(t => t.ArriveTime).ToList();
            foreach (var number in instanceNumbers)
            {
                Dictionary<string, string> approvers = new Dictionary<string, string>();
                approvers.Add("approver1", string.Empty);
                approvers.Add("approver2", string.Empty);
                approvers.Add("approver3", string.Empty);
                approvers.Add("approver4", string.Empty);
                approvers.Add("approver5", string.Empty);
                approvers.Add("approver6", string.Empty);
                approvers.Add("approver7", string.Empty);
                approvers.Add("approver8", string.Empty);
                var activite = activites.Where(t => t.InstanceNumber == number && t.Name != "开始").ToList();
                //var starttime = activite.Where(t => t.Name == "开始").LastOrDefault()?.ArriveTime;
                //activite = activite.Where(t => t.ArriveTime > starttime).ToList();
                var activiteNames = activite.Select(t => t.Name).Distinct().ToList();
                for (int i = 0; i < activiteNames.Count(); i++)
                {
                    var activiteids = activite.Where(t => t.Name == activiteNames[i]).Select(t => t.ActivityId.ToString()).ToList();
                    var names = tasks.Where(t => activiteids.Contains(t.ActivityId))
                            .Select(t => t.UserName).Distinct().ToList();
                    if (i <= 6)
                    {
                        approvers["approver" + (i + 1)] = names.Count() > 0 ? string.Join(",", names) : string.Empty;
                    }
                    else
                    {
                        // 后面多出来的，全塞到8里面
                        if (names.Count() > 0)
                        {
                            if (!string.IsNullOrEmpty(approvers["approver8"]))
                            {
                                approvers["approver8"] = approvers["approver8"] + "," + string.Join(",", names);
                            }
                            else
                            {
                                approvers["approver8"] = string.Join(",", names);
                            }
                        }
                    }
                }
                result.Add(number, approvers);
            }
            return result;
        }

        /// <summary>
        /// 薪资组批量确认
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task BatchConfirmation(List<string> input)
        {
            await _nPRestHttp.PostAsync<string>(_frameOrderBatchConfirUrl, input.ToArray());
        }


        public async Task UpdateBusinessType(string instanceNumber)
        {
            // var result =
            await _db.Updateable<FrameOrderMain>()
                .SetColumns(x => new FrameOrderMain { BusinessType = 2.ToString() })
                .Where(x => x.InstanceNumber == instanceNumber)
            .ExecuteCommandAsync();
        }


        private async Task<ISugarQueryable<GetFrameOrderOutput>> GetQueryable(GetFrameOrderInput input)
        {
            var workNumbers = _commonService.GetUserByRoleFilter(CurrentUser.UserName, Contract.Dtos.RelationshipTypeEnum.HRBP);
            bool isAdmin = workNumbers.Contains("9999999999");

            var splitChat = new char[] { ',', ';', '，', '；' };
            var instanceResult = _db.Queryable<FrameOrderMain, BusinessProcessesNew>((f, b) =>
                    new JoinQueryInfos(JoinType.Left, b.InstanceId == f.InstanceNumber))
                .Where((f, b) => (input.ProcessTopic == "驻外补贴" && f.InstanceNumber.StartsWith("B_") && f.TransportationSubsidy != "0") || (b.InstanceId != null && b.ProcessTopic.Contains(input.ProcessTopic) && b.IsEnd == true && b.ProcessStatusCode == "approved"))
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), (f, b) => b.InstanceId.Contains(input.InstanceNumber))
                .WhereIF((input.BusinessType != null && input.BusinessType != 0), (f, b) => f.BusinessType == input.BusinessType.ToString())
                .WhereIF((input.BusinessType != null && input.BusinessType == 0), (f, b) => f.BusinessType == input.BusinessType.ToString() || f.BusinessType == null)
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName),
                    (f, b) => b.StartUserName == input.AddUserName || f.ApplyName.Contains(input.AddUserName) || f.ApplyNumber.Contains(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null,
                    (f, b) => b.StartTime >= input.StartCreationTime && b.StartTime <= input.EndCreationTime)
                .WhereIF(!string.IsNullOrWhiteSpace(input.ScopePersonnel),
                    (f, b) => input.ScopePersonnel.Split(splitChat, StringSplitOptions.RemoveEmptyEntries).ToArray().Contains(f.ScopePersonnel))
                .WhereIF(!string.IsNullOrWhiteSpace(input.ABKRS),
                    (f, b) => input.ABKRS.Split(splitChat, StringSplitOptions.RemoveEmptyEntries).ToArray().Contains(f.ABKRS))
                .WhereIF(!input.IsAdmin && !isAdmin, (f, b) => SqlFunc.ContainsArray(workNumbers, f.ApplyNumber))
                .OrderBy((f, b) => f.ProcessStartTime, OrderByType.Desc)
                .Select((f, b) => new GetFrameOrderOutput
                {
                    ApplyerJob = f.ApplyerJob,
                    ApplyerRank = f.ApplyerRank,
                    ApplyerTitle = f.ApplyerTitle,
                    ApplyName = f.ApplyName,
                    ApplyNumber = f.ApplyNumber,
                    ApplyTypeSubsidy = f.ApplyTypeSubsidy,
                    ApproveDate = b.FinishTime != null ? b.FinishTime.Value.ToString("yyyy-MM-dd") : "",
                    BusinessType = f.BusinessType,
                    CostType = f.CostType,
                    Department0 = f.Department0,
                    Department1 = f.Department1,
                    Department2 = f.Department2,
                    Department3 = f.Department3,
                    Department4 = f.Department4,
                    Department5 = f.Department5,
                    Department6 = f.Department6,
                    Department7 = f.Department7,
                    Department8 = f.Department8,
                    Department9 = f.Department9,
                    DocApplyType = f.DocApplyType,
                    InstanceNumber = f.InstanceNumber,
                    JobReason = f.JobReason,
                    JoinDate = f.JoinDate != null ? f.JoinDate.Value.ToString("yyyy-MM-dd") : "",
                    ProcessStartTime = f.ProcessStartTime != null ? f.ProcessStartTime.Value.ToString("yyyy-MM-dd") : b.StartTime != null ? b.StartTime.ToString("yyyy-MM-dd") : "",
                    ScopePersonnel = f.ScopePersonnel,
                    // Approve1 = f.JsonData,
                    // Approve2 = f.JsonData,
                    // Approve3 = f.JsonData,
                    // Approve4 = f.JsonData,
                    // Approve5 = f.JsonData,
                    // Approve6 = f.JsonData,
                    // Approve7 = f.JsonData,
                    HRBPFinalSubsidyEndDate = f.HRBPFinalSubsidyEndDate.ToString(),
                    HRBPFinalSubsidystartDate = f.HRBPFinalSubsidystartDate.ToString(),
                    HRBPFinalTransportationSubsidy = f.HRBPFinalTransportationSubsidy,
                    HRBPFinalTransportationSubsidy2 = f.HRBPFinalTransportationSubsidy2,
                    HRBPSubsidyEndDate = f.HRBPSubsidyEndDate,
                    HRBPSubsidystartDate = f.HRBPSubsidystartDate,
                    HRBPTransportationSubsidy = f.HRBPTransportationSubsidy,
                    HRBPTransportationSubsidy2 = f.HRBPTransportationSubsidy2,
                    SubsidyEndDate = f.SubsidyEndDate,
                    SubsidystartDate = f.SubsidystartDate,
                    TransportationSubsidy = f.TransportationSubsidy,
                    TransportationSubsidy2 = f.TransportationSubsidy2,
                    ABKRS = f.ABKRS
                });
            return instanceResult;
        }


        private string GetInstanceType(string instanceId)
        {
            var state = string.Empty;
            var query = _dbEngine
                .Queryable<Instances, InstanceStates>((it, its) => it.InstanceId == its.InstanceId)
                .WhereIF(!string.IsNullOrEmpty(instanceId), (it, its) => it.Number == instanceId)
                .Select((it, its) => new
                {
                    state = its
                }).ToList();

            if (query.Any())
            {
                var s = query.First().state.Status;
                state = ConvertToQueryStatus((TaskCommonStatus)s);
            }

            return state;
        }

        private string ConvertToQueryStatus(TaskCommonStatus status, bool isInnerState = false)
        {
            string queryStatus;

            switch (status)
            {
                case TaskCommonStatus.RecallStart:
                    queryStatus = "待发起";
                    break;
                case TaskCommonStatus.Start:
                case TaskCommonStatus.ReStart:
                    queryStatus = "发起";
                    break;
                case TaskCommonStatus.Processing:
                    queryStatus = "处理中";
                    break;
                case TaskCommonStatus.RejectActivity:
                case TaskCommonStatus.RejectActivityDirect:
                case TaskCommonStatus.Handover:
                case TaskCommonStatus.ExtraAppend:
                case TaskCommonStatus.ExtraInsert:
                case TaskCommonStatus.SkippedWhenEmptyResolver:
                case TaskCommonStatus.SkippedWhenSameApprover:
                    queryStatus = isInnerState ? "已完成" : "处理中";
                    break;
                case TaskCommonStatus.Done:
                    queryStatus = "通过";
                    break;
                case TaskCommonStatus.Refused:
                    queryStatus = "拒绝";
                    break;
                case TaskCommonStatus.Canceled:
                case TaskCommonStatus.InterveneAddNode:
                case TaskCommonStatus.InterveneJumpNode:
                case TaskCommonStatus.InterveneChangeUsers:
                case TaskCommonStatus.InterveneReorder:
                case TaskCommonStatus.InterveneRemoveNode:
                    queryStatus = "终止";
                    break;
                case TaskCommonStatus.RejectStart:
                case TaskCommonStatus.RejectStartDirect:
                    queryStatus = "退回";
                    break;
                case TaskCommonStatus.Exception:
                    queryStatus = "有异常";
                    break;
                case TaskCommonStatus.RecallActivity:
                    queryStatus = "撤回";
                    break;
                default:
                    queryStatus = "待发起";
                    break;
            }

            return queryStatus;
        }

        public string getMoney(GetFrameOrderOutput main, int type)
        {
            string money = string.Empty;
            if (type == 0)
            {
                if (!string.IsNullOrWhiteSpace(main.HRBPFinalTransportationSubsidy))
                {
                    money = main.HRBPFinalTransportationSubsidy;
                }
                else
                {
                    if (!string.IsNullOrWhiteSpace(main.HRBPTransportationSubsidy))
                    {
                        money = main.HRBPTransportationSubsidy;
                    }
                    else
                    {
                        money = main.TransportationSubsidy;
                    }
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(main.HRBPFinalTransportationSubsidy2))
                {
                    money = main.HRBPFinalTransportationSubsidy2;
                }
                else
                {
                    if (!string.IsNullOrWhiteSpace(main.HRBPTransportationSubsidy2))
                    {
                        money = main.HRBPTransportationSubsidy2;
                    }
                    else
                    {
                        money = main.TransportationSubsidy2;
                    }
                }
            }

            return money;
        }

        public string getSubDate(GetFrameOrderOutput main, int type)
        {
            string date = string.Empty;
            if (type == 0)
            {
                if (!string.IsNullOrWhiteSpace(main.HRBPFinalSubsidyEndDate))
                {
                    date = Convert.ToDateTime(main.HRBPFinalSubsidyEndDate).ToString("yyyy-MM-dd");
                }
                else
                {
                    if (main.HRBPSubsidyEndDate.HasValue)
                    {
                        date = main.HRBPSubsidyEndDate.Value.ToString("yyyy-MM-dd");
                    }
                    else
                    {
                        date = main.SubsidyEndDate.HasValue ? main.SubsidyEndDate.Value.ToString("yyyy-MM-dd") : "";
                    }
                }
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(main.HRBPFinalSubsidystartDate))
                {
                    date = Convert.ToDateTime(main.HRBPFinalSubsidystartDate).ToString("yyyy-MM-dd");
                }
                else
                {
                    if (main.HRBPSubsidystartDate.HasValue)
                    {
                        date = main.HRBPSubsidystartDate.Value.ToString("yyyy-MM-dd");
                    }
                    else
                    {
                        date = main.SubsidystartDate.HasValue ? main.SubsidystartDate.Value.ToString("yyyy-MM-dd") : "";
                    }
                }
            }

            return date;
        }

        private string GetBusinessType(string bType)
        {
            string type = "未同步";
            switch (bType)
            {
                case "1":
                    type = "已同步";
                    break;
                case "2":
                    type = "薪资组确认";
                    break;
            }

            return type;
        }

        private string GetDicName(string key, List<Dictionaries> dic)
        {
            string name = string.Empty;
            var result = dic.FirstOrDefault(t => t.Code == key);
            if (result != null)
            {
                name = result.Name;
            }

            return name;
        }

        private string GetUserName(int type, string strJson)
        {
            var json = Newtonsoft.Json.JsonConvert.DeserializeObject<JObject>(strJson.ToLower());
            string name = string.Empty;
            JToken obj = null;
            switch (type)
            {
                case 1:
                    obj = json["approveruserone"];
                    name = GetJTokenName(obj);
                    break;
                case 2:
                    obj = json["approverusertwo"];
                    name = GetJTokenName(obj);
                    break;
                case 3:
                    obj = json["approveruserthree"];
                    name = GetJTokenName(obj);
                    break;
                case 4:
                    obj = json["approveruserfour"];
                    name = GetJTokenName(obj);
                    break;
                case 5:
                    obj = json["approveruserfive"];
                    name = GetJTokenName(obj);
                    break;
                case 6:
                    obj = json["approverusersix"];
                    name = GetJTokenName(obj);
                    break;
                case 7:
                    obj = json["approveruserseven"];
                    name = GetJTokenName(obj);
                    break;
            }
            return name;

        }

        private string GetJTokenName(JToken obj)
        {
            string name = string.Empty;
            if (obj != null && obj.HasValues)
            {
                var t = obj.Value<object>().ToString();
                var ttt = Newtonsoft.Json.JsonConvert.DeserializeObject<JArray>(t);
                foreach (var item in ttt)
                {
                    name += item["username"].Value<object>().ToString() + ",";
                }

            }

            return name.TrimEnd(',');
        }

        private string FormatBusinessType(string code)
        {
            var name = "未推送";
            switch (code)
            {
                case "0":
                    name = "未推送";
                    break;
                case "1":
                    name = "推送成功";
                    break;
                case "2":
                    name = "推送失败";
                    break;
            }
            return name;
        }

        /// <summary>
        /// 获取框架订单推送记录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private ISugarQueryable<GetFraneOrderPushRecordOutput> GetFraneOrderPushRecordQueryable(GetFraneOrderPushRecordInput input)
        {
            RefAsync<int> totalCount = 0;
            var rst = _db.Queryable<FrameOrderUsualAllowance>()
             .Where(a => a.allowance_type.Equals("车辆使用补贴"))
             .WhereIF(!string.IsNullOrWhiteSpace(input.EmployeeNumber), a => a.employeeId.Contains(input.EmployeeNumber))
             .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), (a) => a.InstanceNumber.Contains(input.InstanceNumber))
             .WhereIF(!string.IsNullOrWhiteSpace(input.BusinessType), (a) => a.BusinessType == input.BusinessType)
             .WhereIF(!string.IsNullOrWhiteSpace(input.StartDate), (a) => a.StartDate >= Convert.ToDateTime(input.StartDate))
             .WhereIF(!string.IsNullOrWhiteSpace(input.EndDate), (a) => a.EndDate <= Convert.ToDateTime(input.EndDate))
             .OrderBy(" InstanceNumber desc, year desc ,month*1 desc").Select((a) =>
                  new GetFraneOrderPushRecordOutput
                  {
                      Allowance_Type = a.allowance_type,
                      EmployeeNumber = a.employeeId,
                      EmployeeName = a.employeeName,
                      Allowance_Lines = a.allowance_lines,
                      Year = a.year,
                      Month = a.month,
                      StartDate = a.StartDate == null ? "" : Convert.ToDateTime(a.StartDate).ToString("yyyy-MM-dd"),
                      EndDate = a.EndDate == null ? "" : Convert.ToDateTime(a.EndDate).ToString("yyyy-MM-dd"),
                      InstanceNumber = a.InstanceNumber,
                      ProcessStartTime = a.ProcessStartTime,
                      ApproveDate = a.ApproveDate,
                      InstanceType = a.InstanceType,
                      HRBPApprove = a.HRBPApprove,
                      PushTime = a.PushTime,
                      BusinessType = a.BusinessType,
                      Remarks = a.Remarks,
                      Id = a.ID.ToString(),// 主键
                  });
            return rst;
        }

        /// <summary>
        /// 获取框架订单推送记录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<GetFraneOrderPushRecordOutput>> GetFraneOrderPushRecordAsync(GetFraneOrderPushRecordInput input)
        {
            RefAsync<int> totalCount = 0;

            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);

            var listQueryable = GetFraneOrderPushRecordQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            listViewDto.ForEach(x =>
            {
                x.BusinessTypeName = FormatBusinessType(x.BusinessType);
                x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId);

            });

            //返回结果
            return new PagedResultDto<GetFraneOrderPushRecordOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        /// <summary>
        /// 导出框架订单推送记录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<GetFraneOrderPushRecordOutput>> ExportFraneOrderPushRecordAsync(GetFraneOrderPushRecordInput input)
        {
            var listQueryable = GetFraneOrderPushRecordQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();

            listViewDto.ForEach(x =>
            {
                // 增加流程状态
                x.BusinessTypeName = FormatBusinessType(x.BusinessType);

            });
            return listViewDto;
        }

        public async Task SendThirdSystem(IEnumerable<Guid> ids)
        {
            // FrameOrderUsualAllowance
            var usualData = await _db.Queryable<FrameOrderUsualAllowance>(
            ).Where(x => ids.Contains(x.ID)).ToListAsync();
            //  通过ID查询数据
            var sendData = usualData.Select(item => new ItemData
            {
                code = "车辆使用费(非框架订单)-个人预算",
                fiscal_date = item.year + "-" + item.month.PadLeft(2, '0'),
                budget_amount = item.allowance_lines.ToString(),
                budget_code = "pclsyf2",
                employee_number = item.employeeId
            })
                .ToList();


            if (sendData.Count == 0)
            {// 没有数据
                return;
            }

            string bizId = Guid.NewGuid().ToString();
            string timestamp = ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000).ToString(); // 同步对应的时间戳
            var ydbxTemp = new ESBRequestCloudPense
            {
                bizId = bizId,
                timestamp = timestamp,
                data = sendData
            };

            var headers = new Dictionary<string, string>
            {
                {"requestId", Guid.NewGuid().ToString()},
                {"trackId", Guid.NewGuid().ToString()},
                {"sourceSystem","BPMNEW"},
                {"serviceName", "S_XXX_CloudPense_GetToken_S"} // 获取token
            };

            string tokenUrl = _tokenUrl;
            var tokenResult = await _nPRestHttp.PostAsync<TokenOutput>(tokenUrl, new TokenInput(), headers);

            var token = tokenResult.resCode == 200000 ? tokenResult.data.access_token : "";

            headers["serviceName"] = "S_XXX_CloudPense_BudgetSyn_S";
            headers.Add("accessToken", token);


            // 等待回调
            var content = await _nPRestHttp.PostAsync<dynamic>(_esbNewErpApi, ydbxTemp, headers);
        }

        #region 导入历史框架订单
        /// <summary>
        /// 一次性安家费，探亲次数保持
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private async Task<FrameOrderChildrszwbt> SaveData(FrameOrderImportDto.ImportInput data)
        {
            string number = "B_" + data.WorkNumber + DateTime.Now.ToString("MMddHH");
            // 主表
            FrameOrderMain main = new FrameOrderMain()
            {
                ID = Guid.NewGuid(),
                InstanceNumber = number,
                ProcessStartTime = DateTime.Now,
                CostType = "人事驻外补贴-正常",
                ApplyNumber = data.WorkNumber,
                ApplyName = data.UserName,
                DocApplyType = "xj",
                SubsidystartDate = data.StartDate,
                SubsidyEndDate = data.EndDate,
                TransportationSubsidy = data.Gdjt,
                BusinessType = "0",
                HRBPFinalSubsidyEndDate = data.EndDate,
                HRBPFinalSubsidystartDate = data.StartDate,
            };

            // 存储驻外补贴明细数据
            FrameOrderChildrszwbt child = new FrameOrderChildrszwbt()
            {
                ApplyName = data.UserName,
                ApplyNumber = data.WorkNumber,
                AssignDatebegin = data.StartDate,
                AssignDateend = data.EndDate,
                FamilyVisitsNumber = data.Tqjcs, // 探亲次数
                FixAllowance = data.Gdjt,
                ID = Guid.NewGuid(),
                InstanceNumber = number,
                MainID = main.ID,
                Rent = data.Zfjt,
                RentalAllowance = data.Zfjt,
                SettleFee = data.Ycxajf, // 一次性安家费
            };
            _db.Insertable(main).ExecuteCommand();
            _db.Insertable(child).ExecuteCommand();

            // 推送移动报销(探亲次数 > 0 才推送)
            if (data.Tqjcs.ToOurInt() > 0)
            {
                await PushVisitRetryAsync(child.InstanceNumber);
                //// 一次性安家费，探亲次数 实时推送
                //GetTravelAssignmentESB(child);

                //// 按人员同步差旅外派数据权限接口
                //GetPermissionsESB(child);
            }
            return child;
        }

        /// <summary>
        /// 房租补贴
        /// </summary>
        /// <param name="businessResult"></param>
        /// <param name="start">开始</param>
        /// <param name="end">结束</param>
        private void RentSubsidies_UsfeeAllowance(FrameOrderChildrszwbt businessResult)
        {
            var msg = string.Empty;
            DateTime start = businessResult.AssignDatebegin.Value; // 外派开始
            DateTime end = businessResult.AssignDateend.Value;
            List<FrameOrderUsfeeAllowance> uAList = new List<FrameOrderUsfeeAllowance>();
            var entityUA = _db.Queryable<FrameOrderUsfeeAllowance>()
                .Where(b => b.employeeId == businessResult.ApplyNumber && b.allowance_type == "房租补贴")
                .Where(b => (b.StartDate >= start && b.StartDate <= end) || (b.EndDate >= start && b.EndDate <= end))
                .ToList();

            #region 保存数据
            DateTime repeartDate = start;
            while (true)
            {
                var year = repeartDate.Year.ToString();
                var month = repeartDate.Month.ToString();
                if (repeartDate.Year > end.Year || (repeartDate.Year == end.Year && repeartDate.Month > end.Month))
                {
                    break;
                }

                // 更新，以前申请的，标记为旧数据，不同步出去
                var entityUA_Old = entityUA.FirstOrDefault(t => t.year == year && t.month == month && t.IsOldData == false);
                if (entityUA_Old != null)
                {
                    entityUA_Old.IsOldData = true;
                }

                // 租房津贴
                decimal rentalAllowance = decimal.Parse(businessResult.RentalAllowance);

                // 租金
                decimal rent = decimal.Parse(businessResult.Rent);

                // 房租补贴
                FrameOrderUsfeeAllowance entityUA_info = new FrameOrderUsfeeAllowance();
                entityUA_info.ID = Guid.NewGuid();
                entityUA_info.allowance_type = "房租补贴";
                entityUA_info.department = "立邦";
                entityUA_info.employeeId = businessResult.ApplyNumber;
                entityUA_info.employeeName = businessResult.ApplyName;
                entityUA_info.allowance_lines = rentalAllowance > rent ? rent : rentalAllowance; // 租房津贴和租金，取小
                entityUA_info.year = repeartDate.Year.ToString();
                entityUA_info.month = repeartDate.Month.ToString();
                entityUA_info.day = string.Empty;
                entityUA_info.StartDate = start;
                entityUA_info.EndDate = end;
                entityUA_info.isgaoguan = false;
                entityUA_info.InstanceNumber = businessResult.InstanceNumber;
                entityUA_info.BusinessType = "0";
                entityUA_info.UpdateDate = DateTime.Now;
                uAList.Add(entityUA_info);

                // 增加一个月
                repeartDate = repeartDate.AddMonths(1);
            }

            try
            {
                if (uAList != null && uAList.Count > 0)
                {
                    _db.Insertable(uAList).ExecuteCommand();
                    if (entityUA != null && entityUA.Count > 0)
                    {
                        _db.Updateable(entityUA).UpdateColumns(t => new { t.IsOldData }).ExecuteCommand();
                    }
                }
            }
            catch (Exception ex)
            {
                msg = $"费控津贴表数据保存失败，异常消息：{ex.Message}";
                throw new Exception(msg);
            }

            #endregion
        }

        /// <summary>
        /// 固定补贴
        /// </summary>
        /// <param name="businessResult"></param>
        private void UsualAllowanceDate(FrameOrderChildrszwbt businessResult)
        {
            var sbText = new StringBuilder();
            var msg = string.Empty;
            List<FrameOrderUsualAllowance> uAList = new List<FrameOrderUsualAllowance>();
            DateTime start = businessResult.AssignDatebegin.Value; // 外派开始
            DateTime end = businessResult.AssignDateend.Value;

            // 找到当前所有
            // (车辆购置补贴=1,车辆使用补贴=2,人事驻外补贴=3）流程类型
            string nowYear = businessResult.AssignDatebegin.Value.ToString("yyyy");
            var entityUA = _db.Queryable<FrameOrderUsualAllowance>()
                .Where(b => b.employeeId == businessResult.ApplyNumber && b.allowance_type == "驻外固定补贴")
                .Where(b => (b.StartDate >= start && b.StartDate <= end) || (b.EndDate >= start && b.EndDate <= end))
                .ToList();

            if (entityUA != null && entityUA.Count() > 0)
            {
                _db.Deleteable(entityUA).ExecuteCommand();
            }

            #region 保存数据
            DateTime repeartDate = start;
            while (true)
            {
                if (repeartDate.Year > end.Year || (repeartDate.Year == end.Year && repeartDate.Month > end.Month))
                {
                    break;
                }

                FrameOrderUsualAllowance frameOrderUsual = new FrameOrderUsualAllowance();
                frameOrderUsual.ID = Guid.NewGuid();
                frameOrderUsual.allowance_type = "驻外固定补贴";
                frameOrderUsual.department = "立邦";
                frameOrderUsual.employeeId = businessResult.ApplyNumber;
                frameOrderUsual.employeeName = businessResult.ApplyName;
                decimal transportationSubsidystr = 0;
                decimal.TryParse(businessResult.FixAllowance.ToString(), out transportationSubsidystr);
                frameOrderUsual.allowance_lines = transportationSubsidystr;
                frameOrderUsual.year = repeartDate.Year.ToString();
                frameOrderUsual.month = repeartDate.Month.ToString();
                frameOrderUsual.isgaoguan = false;
                frameOrderUsual.StartDate = start;
                frameOrderUsual.EndDate = end;
                frameOrderUsual.InstanceNumber = businessResult.InstanceNumber;
                frameOrderUsual.BusinessType = "0";
                uAList.Add(frameOrderUsual);

                // 增加一个月
                repeartDate = repeartDate.AddMonths(1);
            }

            try
            {
                if (uAList != null && uAList.Count > 0)
                {
                    _db.Insertable(uAList).ExecuteCommand();
                }
            }
            catch (Exception ex)
            {
                msg = $"驻外固定补贴表数据保存失败，异常消息：{ex.Message}";
                sbText.AppendLine(msg);
                throw new Exception(msg);
            }

            #endregion
        }
        #endregion

        /// <summary>
        /// 将日期转成SF需要的str
        /// 注意，推送给SF的数据，日期要加8H
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public string ToSFStr(DateTime date, bool IsPush = false)
        {
            if (date == null)
            {
                return "0";
            }

            if (IsPush)
            {
                date = date.AddHours(8);
            }

            DateTimeOffset dateTime = new DateTimeOffset(date);
            return string.Format("/Date({0})/", dateTime.ToUnixTimeMilliseconds());
        }
    }
}